package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"sort"
	"time"
)

type PerformanceData struct {
	NodeID            uint64                 `json:"node_id"`
	ElapsedSeconds    float64                `json:"elapsed_seconds"`
	TotalTransactions int                    `json:"total_transactions"`
	TotalEpochs       int                    `json:"total_epochs"`
	ThroughputTPS     float64                `json:"throughput_tps"`
	AvgEpochLatency   float64                `json:"avg_epoch_latency"`
	NetworkStats      NetworkStats           `json:"network_stats"`
	EpochDeliveries   map[string]int         `json:"epoch_deliveries"`
	ComponentLatencies map[string]interface{} `json:"component_latencies"`
}

type NetworkStats struct {
	MessagesSent     int   `json:"MessagesSent"`
	MessagesReceived int   `json:"MessagesReceived"`
	BytesSent        int64 `json:"BytesSent"`
	BytesReceived    int64 `json:"BytesReceived"`
}

func main() {
	logDir := "logs"
	if len(os.Args) > 1 {
		logDir = os.Args[1]
	}

	fmt.Printf("Analyzing performance data from: %s\n", logDir)
	fmt.Println("============================================================")

	// 读取所有性能文件
	files, err := filepath.Glob(filepath.Join(logDir, "node_*_performance.json"))
	if err != nil {
		log.Fatalf("Failed to read log directory: %v", err)
	}

	if len(files) == 0 {
		fmt.Println("No performance files found!")
		return
	}

	var allData []PerformanceData
	totalTransactions := 0
	totalEpochs := 0
	totalThroughput := 0.0
	totalLatency := 0.0
	totalMessagesSent := 0
	totalMessagesReceived := 0
	totalBytesSent := int64(0)
	totalBytesReceived := int64(0)

	// 解析每个节点的性能数据
	for _, file := range files {
		data, err := ioutil.ReadFile(file)
		if err != nil {
			fmt.Printf("Failed to read %s: %v\n", file, err)
			continue
		}

		var perfData PerformanceData
		if err := json.Unmarshal(data, &perfData); err != nil {
			fmt.Printf("Failed to parse %s: %v\n", file, err)
			continue
		}

		allData = append(allData, perfData)
		
		// 累计统计
		totalTransactions += perfData.TotalTransactions
		totalEpochs += perfData.TotalEpochs
		totalThroughput += perfData.ThroughputTPS
		totalLatency += perfData.AvgEpochLatency
		totalMessagesSent += perfData.NetworkStats.MessagesSent
		totalMessagesReceived += perfData.NetworkStats.MessagesReceived
		totalBytesSent += perfData.NetworkStats.BytesSent
		totalBytesReceived += perfData.NetworkStats.BytesReceived
	}

	// 按节点ID排序
	sort.Slice(allData, func(i, j int) bool {
		return allData[i].NodeID < allData[j].NodeID
	})

	// 输出总体统计
	fmt.Printf("Overall Performance Summary:\n")
	fmt.Printf("  Nodes: %d\n", len(allData))
	fmt.Printf("  Total Transactions: %d\n", totalTransactions)
	fmt.Printf("  Total Epochs: %d\n", totalEpochs)
	fmt.Printf("  Average Throughput: %.2f TPS\n", totalThroughput/float64(len(allData)))
	fmt.Printf("  Average Latency: %.2f ms\n", totalLatency/float64(len(allData)))
	fmt.Printf("  Total Messages: %d sent, %d received\n", totalMessagesSent, totalMessagesReceived)
	fmt.Printf("  Total Bytes: %d sent, %d received\n", totalBytesSent, totalBytesReceived)
	fmt.Println()

	// 输出每个节点的详细统计
	fmt.Printf("Per-Node Performance:\n")
	fmt.Printf("%-6s %-8s %-12s %-8s %-12s %-8s %-8s\n", 
		"Node", "Epochs", "Transactions", "TPS", "Latency(ms)", "Sent", "Received")
	fmt.Printf("%-6s %-8s %-12s %-8s %-12s %-8s %-8s\n", 
		"----", "------", "-----------", "---", "-----------", "----", "--------")

	for _, data := range allData {
		fmt.Printf("%-6d %-8d %-12d %-8.2f %-12.2f %-8d %-8d\n",
			data.NodeID, data.TotalEpochs, data.TotalTransactions,
			data.ThroughputTPS, data.AvgEpochLatency,
			data.NetworkStats.MessagesSent, data.NetworkStats.MessagesReceived)
	}
	fmt.Println()

	// 输出epoch交付统计
	fmt.Printf("Epoch Delivery Analysis:\n")
	epochStats := make(map[string]int)
	for _, data := range allData {
		for epoch, count := range data.EpochDeliveries {
			epochStats[epoch] += count
		}
	}

	if len(epochStats) > 0 {
		var epochs []string
		for epoch := range epochStats {
			epochs = append(epochs, epoch)
		}
		sort.Strings(epochs)

		fmt.Printf("  Epoch Deliveries:\n")
		for _, epoch := range epochs {
			fmt.Printf("    Epoch %s: %d transactions\n", epoch, epochStats[epoch])
		}
	} else {
		fmt.Printf("  No epoch deliveries recorded\n")
	}
	fmt.Println()

	// 输出组件延迟统计
	fmt.Printf("Component Latency Analysis:\n")
	componentStats := make(map[string][]float64)
	for _, data := range allData {
		for component, stats := range data.ComponentLatencies {
			if statsMap, ok := stats.(map[string]interface{}); ok {
				if avgLatency, ok := statsMap["avg_latency"].(float64); ok {
					componentStats[component] = append(componentStats[component], avgLatency)
				}
			}
		}
	}

	if len(componentStats) > 0 {
		for component, latencies := range componentStats {
			if len(latencies) > 0 {
				var total float64
				for _, latency := range latencies {
					total += latency
				}
				avg := total / float64(len(latencies))
				fmt.Printf("  %s: %.2f ms (from %d nodes)\n", component, avg, len(latencies))
			}
		}
	} else {
		fmt.Printf("  No component latency data recorded\n")
	}

	fmt.Println("============================================================")
	fmt.Printf("Analysis completed at %s\n", time.Now().Format("2006-01-02 15:04:05"))
}
